{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f961801a-6025-4b73-be3b-c3a8a75d4167",
   "metadata": {},
   "source": [
    "# Agent Executor\n",
    "\n",
    "This notebook walks through an example creating an agent executor to work with an existing LangChain agent.\n",
    "This is useful for getting started quickly.\n",
    "However, it is highly likely you will want to customize the logic - for information on that, check out the other examples in this folder."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6dd032b-bfe9-458c-a8ef-a14c78e0ad3f",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "First we need to install the packages required"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1759bc06-8af3-4b73-abbf-0be3fa4c31fb",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install --quiet -U langchain langchain_openai tavily-python"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa08bd1a-efaa-46f5-adf8-47a84f738381",
   "metadata": {},
   "source": [
    "Next, we need to set API keys for OpenAI (the LLM we will use) and Tavily (the search tool we will use)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb8e51dc-028b-4ea5-9847-f22fcbed6dac",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import getpass\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\n",
    "os.environ[\"TAVILY_API_KEY\"] = getpass.getpass(\"Tavily API Key:\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9242c0d7-b1da-41a0-9a3e-ed3afab3528e",
   "metadata": {},
   "source": [
    "Optionally, we can set API key for [LangSmith tracing](https://smith.langchain.com/), which will give us best-in-class observability."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5db4438c-7802-4050-9dd9-14a6cac21a91",
   "metadata": {},
   "outputs": [],
   "source": [
    "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"LangSmith API Key:\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ae180d9-abd3-4a44-8fb1-a2c89434fbeb",
   "metadata": {},
   "source": [
    "## Set up LangChain Agent\n",
    "\n",
    "First, will set up our LangChain Agent. \n",
    "See documentation [here](https://python.langchain.com/docs/modules/agents/) for more information on what these agents are and how to think about them"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e2fdcac4-d134-402b-b423-b0cf4b939f5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain import hub\n",
    "from langchain.agents import create_openai_functions_agent\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "afb59979-c7a3-435f-b147-f8d501f6ff13",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [TavilySearchResults(max_results=1)]\n",
    "\n",
    "# Get the prompt to use - you can modify this!\n",
    "prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
    "\n",
    "# Choose the LLM that will drive the agent\n",
    "llm = ChatOpenAI(model=\"gpt-3.5-turbo-1106\")\n",
    "\n",
    "# Construct the OpenAI Functions agent\n",
    "agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0bcb5ff8-b2d1-4fb2-bed4-3726f96db772",
   "metadata": {},
   "source": [
    "## Create agent executor\n",
    "\n",
    "Now we will use the high level method to create the agent executor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7a138eb4-a469-4b30-a059-99d6ea944648",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langgraph.prebuilt import create_agent_executor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9be722f0-c9ab-4bd2-af27-66adf51134d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "app = create_agent_executor(agent_runnable, tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "019b591b-fd71-4ee8-ae94-06d0e2dc6a4d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'agent_outcome': AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'current weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'current weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"current weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})])}\n",
      "----\n",
      "{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'current weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'current weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"current weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})]), \"[{'url': 'https://en.climate-data.org/north-america/united-states-of-america/california/san-francisco-385/t/january-1/', 'content': 'San Francisco Weather in January  you can find all information about the weather in San Francisco in January:  San Francisco weather in January San Francisco weather by month // weather averages 9.6 (49.2) 6.2 (43.2) 14 (57.3) 113  San Francisco weather in January // weather averages Airport close to San FranciscoWeather ☀ ⛅ San Francisco ☀ ⛅ January ☀ ⛅ Information on temperature, sunshine hours, water temperature & rainfall in January for San Francisco. ... Are you planning a holiday with hopefully nice weather in San Francisco in January 2024? Here you can find all information about the weather in San Francisco in January: ... 15. January ...'}]\")]}\n",
      "----\n",
      "{'agent_outcome': AgentFinish(return_values={'output': \"I couldn't find the current weather in San Francisco. However, you can visit a reliable weather website or check a weather app for the most up-to-date information.\"}, log=\"I couldn't find the current weather in San Francisco. However, you can visit a reliable weather website or check a weather app for the most up-to-date information.\")}\n",
      "----\n",
      "{'input': 'what is the weather in sf', 'chat_history': [], 'agent_outcome': AgentFinish(return_values={'output': \"I couldn't find the current weather in San Francisco. However, you can visit a reliable weather website or check a weather app for the most up-to-date information.\"}, log=\"I couldn't find the current weather in San Francisco. However, you can visit a reliable weather website or check a weather app for the most up-to-date information.\"), 'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'current weather in San Francisco'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'current weather in San Francisco'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"current weather in San Francisco\"}', 'name': 'tavily_search_results_json'}})]), \"[{'url': 'https://en.climate-data.org/north-america/united-states-of-america/california/san-francisco-385/t/january-1/', 'content': 'San Francisco Weather in January  you can find all information about the weather in San Francisco in January:  San Francisco weather in January San Francisco weather by month // weather averages 9.6 (49.2) 6.2 (43.2) 14 (57.3) 113  San Francisco weather in January // weather averages Airport close to San FranciscoWeather ☀ ⛅ San Francisco ☀ ⛅ January ☀ ⛅ Information on temperature, sunshine hours, water temperature & rainfall in January for San Francisco. ... Are you planning a holiday with hopefully nice weather in San Francisco in January 2024? Here you can find all information about the weather in San Francisco in January: ... 15. January ...'}]\")]}\n",
      "----\n"
     ]
    }
   ],
   "source": [
    "inputs = {\"input\": \"what is the weather in sf\", \"chat_history\": []}\n",
    "for s in app.stream(inputs):\n",
    "    print(list(s.values())[0])\n",
    "    print(\"----\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c6a664cd-083e-4d85-aeaf-501463881f05",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AgentFinish(return_values={'output': \"I couldn't find the current weather in San Francisco. However, you can check the weather on a reliable weather website or using a weather app for the most up-to-date information.\"}, log=\"I couldn't find the current weather in San Francisco. However, you can check the weather on a reliable weather website or using a weather app for the most up-to-date information.\")"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[\"__end__\"][\"agent_outcome\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7bd3e55-ee7e-4276-81bd-39e6131fcf77",
   "metadata": {},
   "source": [
    "## Custom Input Schema\n",
    "\n",
    "By default, the `create_agent_executor` assumes that the input will be a dictionary with two keys: `input` and `chat_history`. \n",
    "If this is not the case, you can easily customize the input schema.\n",
    "You should do this, by defining a schema as a TypedDict.\n",
    "\n",
    "For this example, we will create a new agent that expects `question` and `language` as inputs."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a98c5ec5-f836-4b3c-b37b-00102b496366",
   "metadata": {},
   "source": [
    "### Create New Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "676841ec-b5a6-495e-a88a-7eb0ab3cbae6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
    "\n",
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\n",
    "            \"human\",\n",
    "            \"Respond to the user question: {question}. Answer in this language: {language}\",\n",
    "        ),\n",
    "        MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
    "    ]\n",
    ")\n",
    "agent_runnable = create_openai_functions_agent(llm, tools, prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5889d980-d209-447b-8489-1d4873acfdc2",
   "metadata": {},
   "source": [
    "### Define Input Schema"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3d1df06d-1564-46a1-a72f-58dfc65927bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import TypedDict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2fdbb687-9c72-42c7-afcb-3f8940f3e5f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "class InputSchema(TypedDict):\n",
    "    question: str\n",
    "    language: str"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "329bb518-02a8-477c-8898-d04cb64fc460",
   "metadata": {},
   "source": [
    "### Create new agent executor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1ad88990-896d-48d5-bd34-01c9f6a37734",
   "metadata": {},
   "outputs": [],
   "source": [
    "app = create_agent_executor(agent_runnable, tools, input_schema=InputSchema)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "13ffa18c-9a9f-4e0e-8298-32aeff94ce5d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'agent_outcome': AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'che tempo fa a sf'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'che tempo fa a sf'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"che tempo fa a sf\"}', 'name': 'tavily_search_results_json'}})])}\n",
      "----\n",
      "{'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'che tempo fa a sf'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'che tempo fa a sf'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"che tempo fa a sf\"}', 'name': 'tavily_search_results_json'}})]), '[{\\'url\\': \\'https://www.mxbars.net/2024/01/14/san-francisco-supercross-2024-results-and-points-video/\\', \\'content\\': \"Scritto domenica 14 Gennaio 2024 alle 04:38. SAN FRANCISCO Oracle Park, CA January 13, 2024  sera gli orari sono anticipati di due ore causa mal tempo per non compromettere lo spettacolo!  secondo weekend con la seconda tappa e pista molto tecnica per San Francisco dove sta piovendo e lo stadio aperto non  . Commenta la gara\\\\xa0CLICCANDO\\\\xa0il link! http://forum.mxbars.net/viewtopic.php?f=18&t=50182SAN FRANCISCO. Oracle Park, CA. January 13, 2024. Ecco che la NUOVA stagione del Monster Energy Supercross 2024 continua, dopo Anaheim 1 si passa al secondo weekend con la seconda tappa e pista molto tecnica per San Francisco dove sta piovendo e lo stadio aperto non vede possibilità di chiudersi, per la lotta nella 450 dove sono tutti agguerriti e quest\\'anno il livello è ancora più alto ...\"}]')]}\n",
      "----\n",
      "{'agent_outcome': AgentFinish(return_values={'output': 'Al momento sta piovendo a San Francisco.'}, log='Al momento sta piovendo a San Francisco.')}\n",
      "----\n",
      "{'question': 'what is the weather in sf', 'language': 'italian', 'agent_outcome': AgentFinish(return_values={'output': 'Al momento sta piovendo a San Francisco.'}, log='Al momento sta piovendo a San Francisco.'), 'intermediate_steps': [(AgentActionMessageLog(tool='tavily_search_results_json', tool_input={'query': 'che tempo fa a sf'}, log=\"\\nInvoking: `tavily_search_results_json` with `{'query': 'che tempo fa a sf'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"che tempo fa a sf\"}', 'name': 'tavily_search_results_json'}})]), '[{\\'url\\': \\'https://www.mxbars.net/2024/01/14/san-francisco-supercross-2024-results-and-points-video/\\', \\'content\\': \"Scritto domenica 14 Gennaio 2024 alle 04:38. SAN FRANCISCO Oracle Park, CA January 13, 2024  sera gli orari sono anticipati di due ore causa mal tempo per non compromettere lo spettacolo!  secondo weekend con la seconda tappa e pista molto tecnica per San Francisco dove sta piovendo e lo stadio aperto non  . Commenta la gara\\\\xa0CLICCANDO\\\\xa0il link! http://forum.mxbars.net/viewtopic.php?f=18&t=50182SAN FRANCISCO. Oracle Park, CA. January 13, 2024. Ecco che la NUOVA stagione del Monster Energy Supercross 2024 continua, dopo Anaheim 1 si passa al secondo weekend con la seconda tappa e pista molto tecnica per San Francisco dove sta piovendo e lo stadio aperto non vede possibilità di chiudersi, per la lotta nella 450 dove sono tutti agguerriti e quest\\'anno il livello è ancora più alto ...\"}]')]}\n",
      "----\n"
     ]
    }
   ],
   "source": [
    "inputs = {\"question\": \"what is the weather in sf\", \"language\": \"italian\"}\n",
    "for s in app.stream(inputs):\n",
    "    print(list(s.values())[0])\n",
    "    print(\"----\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "fd60f5d6-bd4b-4995-80dd-63f268c17cff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AgentFinish(return_values={'output': 'Il clima a San Francisco durante il mese di gennaio è generalmente fresco con temperature medie di circa 9.6°C (49.2°F) e massime di 14°C (57.3°F). Si consiglia di prepararsi a temperature fresche se si pianifica una visita a San Francisco in gennaio.'}, log='Il clima a San Francisco durante il mese di gennaio è generalmente fresco con temperature medie di circa 9.6°C (49.2°F) e massime di 14°C (57.3°F). Si consiglia di prepararsi a temperature fresche se si pianifica una visita a San Francisco in gennaio.')"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[\"__end__\"][\"agent_outcome\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20cac1a0-0c51-4cbd-ae27-929d71db2b56",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
